import 'dart:async';
import 'dart:ui';

import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:largefriends/net/lf_api_util.dart';
import 'package:largefriends/pages/lf_chat_detail/widget/LfMessageAblumApproved.dart';
import 'package:largefriends/pages/lf_chat_detail/widget/LfMessageAblumRequest.dart';
import 'package:largefriends/pages/lf_chat_detail/widget/LfMessageAudio.dart';
import 'package:largefriends/pages/lf_chat_detail/widget/LfMessageCompanion.dart';
import 'package:largefriends/pages/lf_chat_detail/widget/LfMessageImage.dart';
import 'package:largefriends/pages/lf_chat_detail/widget/LfMessageMatch.dart';
import 'package:largefriends/pages/lf_chat_detail/widget/LfMessagePremiumWink.dart';
import 'package:largefriends/pages/lf_chat_detail/widget/LfMessageReply.dart';
import 'package:largefriends/pages/lf_chat_detail/widget/LfMessageStickerAnim.dart';
import 'package:largefriends/pages/lf_chat_detail/widget/LfMessageStickerIcon.dart';
import 'package:largefriends/pages/lf_chat_detail/widget/LfMessageText.dart';
import 'package:largefriends/pages/lf_chat_detail/widget/LfMessageTips.dart';
import 'package:largefriends/pages/lf_chat_detail/widget/LfMessageUnsupport.dart';
import 'package:largefriends/pages/lf_chat_detail/widget/LfMessageUploadPhoto.dart';
import 'package:largefriends/pages/lf_chat_detail/widget/LfMessageVerfify.dart';
import 'package:largefriends/pages/lf_chat_detail/widget/LfMessageWink.dart';
import 'package:largefriends/pages/lf_edit_profile/lf_edit_profile_logic.dart';
import 'package:largefriends/pages/lf_manage_access/lf_manage_access_logic.dart';
import 'package:largefriends/pages/lf_report/lf_report_logic.dart';
import 'package:largefriends/res/lf_color.dart';
import 'package:largefriends/res/lf_double_ext.dart';
import 'package:largefriends/res/lf_string_ext.dart';
import 'package:largefriends/res/strings/lf_strings.dart';
import 'package:largefriends/service/im/lf_im_server_msg_ext.dart';
import 'package:largefriends/utils/lf_keyboard.dart';
import 'package:largefriends/widgets/custom_cache_image.dart';
import 'package:largefriends/widgets/dialog_action_tip.dart';
import 'package:largefriends/widgets/dialog_action_sheet.dart';

import '../../config/lf_im_type.dart';
import '../../res.dart';
import '../../res/lf_fonts.dart';
import '../../res/lf_text_style.dart';
import '../../res/lf_widget_ext.dart';
import '../../utils/lf_scroll_behavior.dart';
import '../../widgets/lf_app_bar.dart';
import '../../widgets/lf_button.dart';
import '../lf_image_gallery/lf_image_gallery_logic.dart';
import 'lf_chat_detail_logic.dart';
import 'widget/LfChatBottom.dart';
import 'widget/LfMessageTime.dart';

class LfChatDetailPage extends StatefulWidget {
  const LfChatDetailPage({super.key});

  @override
  State<LfChatDetailPage> createState() => _LfChatDetailPageState();
}

class _LfChatDetailPageState extends State<LfChatDetailPage> {
  late String otherUid;
  final logic = Get.put(LfChatDetailLogic());

  @override
  void initState() {
    otherUid = Get.arguments['uid'];
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return GetBuilder<LfChatDetailLogic>(
      builder: (logic) {
        return GestureDetector(
          onTap: () {
            closeSoftKeyboard();
            logic.isShowSticker.value = false;
            logic.isShowAudio.value = false;
          },
          child: SafeArea(
            top: false,
            bottom: true,
            child: Scaffold(
              resizeToAvoidBottomInset: true,
              appBar: _getAppBar(logic),
              body: _getBody(logic),
            ),
          ),
        );
      },
    );
  }

  _getAppBar(LfChatDetailLogic logic) {
    if (logic.other?.isSupport() == true) {
      return lfAppBar(
        leadingCallback: () {
          Get.back();
        },
        title: strSupport.tr,
        actions: [
          InkWell(
            child: const Icon(Icons.more_vert_outlined),
            onTap: () {
              showActionSheet(actions: [
                ActionSheetItem(
                    action: () async {
                      await showActionTips(
                        tips: strDeleteConversationTip.tr,
                        actionButtonTip: strSure.tr,
                        action: () async {
                          await deleteConversation(uid: logic.otherUid);
                        },
                      );
                    },
                    title: strDeleteConversation.tr),
              ]);
            },
          )
        ],
      );
    } else {
      var url = logic.other?.avatar;
      if (logic.other?.isHiddenForMe() == true ||
          logic.other?.isBlockMe() == true ||
          logic.other?.isEnable() == false) {
        url = "";
      }
      return AppBar(
        leading: InkWell(
          child: Icon(
            Icons.arrow_back,
            color: colorFF007F,
          ),
          onTap: () {
            Get.back();
          },
        ),
        automaticallyImplyLeading: false,
        centerTitle: false,
        titleSpacing: 1.w,
        title: InkWell(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.start,
            children: [
              10.w.sbw,
              CustomCacheImage(
                imageUrl: url,
                isCircle: true,
                width: 28.r,
                height: 28.r,
              ),
              10.w.sbw,
              Flexible(
                  child: Text(
                logic.other?.username.toUpperCase() ?? strChat.tr,
                style: lfTextStyle(fontFamily: fontMedium, sp: 18.sp),
                maxLines: 1,
                overflow: TextOverflow.ellipsis,
              )),
              logic.other?.isVerified() == true
                  ? Padding(
                      padding: EdgeInsets.only(left: 5.w),
                      child: Image.asset(Res.ic_verified, width: 16.r),
                    )
                  : empty,
              logic.other?.isGold() == true
                  ? Padding(
                      padding: EdgeInsets.only(left: 5.w),
                      child: Image.asset(
                        Res.icon_premium,
                        width: 18.r,
                        color: colorFF007F,
                      ),
                    )
                  : empty,
              10.w.sbw,
            ],
          ),
          onTap: () {
            logic.jumpProfile();
          },
        ),
        actions: [
          InkWell(
            child: const Icon(Icons.more_vert_outlined),
            onTap: () {
              _showMoreAction(logic);
            },
          )
        ],
      );
    }
  }

  _getBody(LfChatDetailLogic logic) {
    return Stack(
      children: [
        Column(
          children: [
            Expanded(
              child: Stack(
                children: [
                  Align(
                    alignment: Alignment.topCenter,
                    child: _messageList(logic),
                  ),
                ],
              ),
            ),
            logic.other?.isSupport() == true
                ? _supportBottom()
                : LfChatBottom(
                    type: BottomType.normal,
                    isCanChat: logic.canChat,
                    isShowSticker: logic.isShowSticker,
                    isShowAudio: logic.isShowAudio,
                    focusNode: logic.focusNode,
                    textEditingController: logic.textEditingController,
                    replyMessage: logic.replyMessage,
                    sendTextMessage: (value) {
                      logic.sendTextMessage(value);
                    },
                    sendStickerMessage: (value) {
                      logic.sendStickerMessage(value: value);
                    },
                    sendImageMessage: (value) {
                      logic.sendImageMessage(value);
                    },
                    sendRecordMessage: (file, duration) {
                      logic.sendAudioMessage(file, duration: duration);
                    },
                  )
          ],
        )
      ],
    );
  }

  _messageList(LfChatDetailLogic chatLogic) {
    final throttleFunction = throttle((index) async {
      var messages = chatLogic.getMessages();
      if (messages.isEmpty) {
        await chatLogic.getHistory(lastId: '0');
      } else {
        await chatLogic.getHistory(lastId: messages.last.historyId ?? "0");
      }
    }, 100);

    return ScrollConfiguration(
        behavior: LfScrollBehavior(),
        child: LayoutBuilder(builder: (context, constant) {
          return ListView.custom(
            childrenDelegate: SliverChildBuilderDelegate(
              (context, index) {
                if (index == 0) {
                  return 20.h.sbh;
                }

                ///列表从下到上依次展示为: 空隙----消息---profile
                if (index == chatLogic.getMessages().length + 1) {
                  if (chatLogic.getMessages().length > 15) {
                    return empty;

                    ///如果大于15个了,没必要显示这个card了,免得每次拉到头看到心烦
                  }
                  if (chatLogic.other?.isSupport() == true) {
                    return empty;
                  }
                  return _profileCard(chatLogic);
                }
                if (index == chatLogic.getMessages().length) {
                  if (chatLogic.getMessages().length > 30) {
                    throttleFunction(index);
                  }
                }
                return _buildMessageItem(chatLogic, index - 1);
              },
              childCount: chatLogic.getMessages().length + 2,

              ///底部显示一些空隙
            ),
            reverse: true,
            shrinkWrap: true,
            cacheExtent: 400,
            dragStartBehavior: DragStartBehavior.down,
          );
        }));
  }

  Widget _profileCard(LfChatDetailLogic chatLogic) {
    if (chatLogic.other?.isHiddenForMe() == true ||
        chatLogic.other?.isBlockMe() == true ||
        chatLogic.other?.isEnable() == false) {
      return empty;
    }
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 15.h),
      child: InkWell(
        child: ClipRRect(
          borderRadius: 14.r.radius,
          child: SizedBox(
            height: 100.h,
            width: ScreenUtil().screenWidth - 20.w,
            child: Stack(
              children: [
                ImageFiltered(
                  imageFilter: ImageFilter.blur(sigmaX: 15, sigmaY: 15),
                  child: CustomCacheImage(
                    imageUrl: chatLogic.other?.avatar,
                    height: 100.h,
                    width: ScreenUtil().screenWidth,
                    radius: 14.r,
                  ),
                ),
                Positioned(
                    child: Container(
                  height: 100.h,
                  width: ScreenUtil().screenWidth,
                  color: Colors.black12,
                )),
                Align(
                  alignment: Alignment.center,
                  child: Row(
                    children: [
                      10.w.sbw,
                      CustomCacheImage(
                        imageUrl: chatLogic.other?.avatar,
                        width: 80.r,
                        height: 80.r,
                        radius: 14.r,
                        boxBorder: Border.all(color: colorFEFEFE, width: 2.r),
                      ),
                      10.w.sbw,
                      Expanded(
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            Row(
                              children: [
                                Flexible(
                                    child: Text(
                                  chatLogic.other?.username.toUpperCase() ?? "",
                                  style: lfTextStyle(
                                      sp: 15.sp,
                                      fontFamily: fontMedium,
                                      color: Colors.white),
                                  maxLines: 1,
                                  textWidthBasis: TextWidthBasis.longestLine,
                                  overflow: TextOverflow.ellipsis,
                                )),
                                // chatLogic.other?.isGold() == true
                                //     ? Padding(
                                //   padding: EdgeInsets.only(left: 5.w),
                                //   child:
                                //   Image.asset(Res.profile_gold_icon),
                                // )
                                //     : empty,
                                // chatLogic.other?.isVerified() == true
                                //     ? Padding(
                                //   padding: EdgeInsets.only(left: 5.w),
                                //   child: Image.asset(
                                //       Res.profile_verify_icon),
                                // )
                                //     : empty,
                                chatLogic.other?.isOnline() == true
                                    ? Padding(
                                        padding: EdgeInsets.only(left: 5.w),
                                        child: Container(
                                          decoration: const BoxDecoration(
                                              color: Colors.lightGreen,
                                              shape: BoxShape.circle),
                                          width: 10.r,
                                          height: 10.r,
                                        ),
                                      )
                                    : chatLogic.other?.isOnlineRecently() ==
                                            true
                                        ? Padding(
                                            padding: EdgeInsets.only(left: 5.w),
                                            child: Container(
                                              decoration: BoxDecoration(
                                                  border: Border.all(
                                                      color: Colors.lightGreen,
                                                      width: 2.r),
                                                  shape: BoxShape.circle),
                                              width: 10.r,
                                              height: 10.r,
                                            ),
                                          )
                                        : empty,
                              ],
                            ),
                            Text(
                              chatLogic.other?.getGenderWithAgeLiveIn() ?? "",
                              style: lfTextStyle(
                                  sp: 13.sp,
                                  fontFamily: fontRegular,
                                  color: colorFEFEFE),
                              maxLines: 2,
                              overflow: TextOverflow.ellipsis,
                            )
                          ],
                        ),
                      ),
                      10.w.sbw,
                    ],
                  ),
                )
              ],
            ),
          ),
        ),
        onTap: () {
          chatLogic.jumpProfile();
        },
      ),
    );
  }

  Widget _buildMessageItem(LfChatDetailLogic chatLogic, int index) {
    var data =
        chatLogic.imService.getMessageListFromMemory(chatLogic.otherUid)[index];
    var isSender = data.sender?.profile?.userId ==
        chatLogic.authService.currentAccount!.userId;
    var messageType = IMMessageType.values.firstWhere(
        (element) => element.value.toString() == data.messageType,
        orElse: () => IMMessageType.messageTypeUnknow);
    return LayoutBuilder(builder: (context, constraints) {
      Widget? msgWidget;
      switch (messageType) {
        case IMMessageType.match:
          bool isBlockMe = chatLogic.other?.isBlockMe() ?? false;
          bool isHidden = chatLogic.other?.isHiddenForMe() ?? false;
          msgWidget = LfMessageMatch(
            data: data,
            avatar: (isHidden || isBlockMe)
                ? Res.common_gender_man
                : chatLogic.other?.avatar ?? Res.common_gender_man,
          );
          break;
        case IMMessageType.verifyNotification:
          msgWidget = const LfMessageVerify();
          break;
        case IMMessageType.text:
        case IMMessageType.supportText:
        case IMMessageType.autoReply:
        case IMMessageType.inviteCompanion:
          msgWidget = LfMessageText(
            data: data,
            recall: () {
              chatLogic.recallMessage(data);
            },
            report: () {
              chatLogic.reportMessage(data);
            },
            isSupport: chatLogic.other?.isSupport() == true,
            reply: () {
              chatLogic.replyMessage.value = data;
              showSoftKeyboard(chatLogic.focusNode);
            },
            canShowMenu: needShowTipMenu(data, chatLogic),
          );
          break;
        case IMMessageType.messageTypeRequestUploadPhoto:
          msgWidget = LfMessageUploadPhoto(
            data: data,
            click: () {
              closeSoftKeyboard();
              logic.stopPlayAudio();
              toEditProfilePage();
            },
          );
          break;
        case IMMessageType.reply:
          msgWidget = LfMessageReply(
            data: data,
            recall: () {
              chatLogic.recallMessage(data);
            },
            report: () {
              chatLogic.reportMessage(data);
            },
            reply: () {
              chatLogic.replyMessage.value = data;
              showSoftKeyboard(chatLogic.focusNode);
            },
            canShowMenu: needShowTipMenu(data, chatLogic),
          );
          break;
        case IMMessageType.wink:
          msgWidget = LfMessageWink(data: data);
          break;
        case IMMessageType.messageTypeTips:
          msgWidget = LfMessageTip(
            message: data.message ?? "",
          );
          break;
        case IMMessageType.messageTypeRecall:
          var tipText = isSender
              ? strYouUnsentMessage.tr
              : '${data.sender?.profile?.username?.toUpperCase()} ${strHasUnsentMessage.tr}';
          msgWidget = LfMessageTip(
            message: tipText,
          );
          break;
        case IMMessageType.privateAlbumRequest:
          msgWidget = LfMessageAlbumRequest(
            data: data,
            other: chatLogic.other,
            accept: () {
              closeSoftKeyboard();
              logic.stopPlayAudio();
              toManageAccess();
            },
          );
          break;
        case IMMessageType.acceptPrivateAlbumRequest:
          msgWidget = LfMessageAlbumApproved(
            data: data,
            other: chatLogic.other,
            check: () {
              chatLogic.jumpProfile();
            },
          );
          break;
        case IMMessageType.voice:
          msgWidget = Obx(() {
            bool isCurrent = false;
            if (chatLogic.audioUrl.value == data.url &&
                (data.url.isNullOrEmpty == false)) {
              isCurrent = true;
            }
            return LfMessageAudio(
              data: data,
              recall: () {
                chatLogic.recallMessage(data);
              },
              report: () {
                chatLogic.reportMessage(data);
              },
              clickAction: () async {
                if (isCurrent) {
                  if (chatLogic.audioPlayer.state == PlayerState.playing) {
                    await chatLogic.audioPlayer.pause();
                  } else {
                    await chatLogic.audioPlayer.resume();
                  }
                } else {
                  if (chatLogic.audioUrl.value.isNotEmpty) {
                    await chatLogic.audioPlayer.stop();
                    chatLogic.audioDuration.value = 0;
                    chatLogic.audioUrl.value = '';
                  }
                  await chatLogic.audioPlayer.play(UrlSource(data.url!));
                  chatLogic.audioUrl.value = data.url!;
                }
              },
              currentDuration: chatLogic.audioDuration.value.toDouble(),
              playerState: chatLogic.playerState.value,
              isCurrent: isCurrent,
              canShowMenu: needShowTipMenu(data, chatLogic),
            );
          });
          break;
        case IMMessageType.image:
        case IMMessageType.customSticker:
          msgWidget = LfMessageImage(
            data: data,
            recall: () {
              chatLogic.recallMessage(data);
            },
            report: () {
              chatLogic.reportMessage(data);
            },
            canShowMenu: needShowTipMenu(data, chatLogic),
            click: () {
              closeSoftKeyboard();
              logic.stopPlayAudio();
              toImageGalleryByMessage(
                entity: data,
              );
            },
          );
          break;
        case IMMessageType.stickerAnim:
          msgWidget = LfMessageStickerAnim(
            data: data,
            recall: () {
              chatLogic.recallMessage(data);
            },
            report: () {
              chatLogic.reportMessage(data);
            },
            canShowMenu: needShowTipMenu(data, chatLogic),
          );
          break;
        case IMMessageType.stickerIcon:
          msgWidget = LfMessageStickerIcon(
            data: data,
            recall: () {
              chatLogic.recallMessage(data);
            },
            report: () {
              chatLogic.replyMessage.value = data;
              showSoftKeyboard(chatLogic.focusNode);
            },
            canShowMenu: needShowTipMenu(data, chatLogic),
          );
          break;
        case IMMessageType.likeCompanion:
        case IMMessageType.joinCompanion:
        case IMMessageType.approvedCompanion:
        case IMMessageType.rehostCompanion:
          msgWidget = LfMessageCompanionWidget(
            data: data,
            userName: chatLogic.other?.username ?? "",
          );
          break;
        case IMMessageType.premiumWink:
          msgWidget = LfMessagePremiumWink(data: data);
          break;
        default:
          msgWidget = LfMessageUnSupport(data: data);
          break;
      }
      return Column(
        mainAxisSize: MainAxisSize.min,
        mainAxisAlignment: MainAxisAlignment.start,
        children: [
          3.h.sbh,
          LfMessageTime(data: data),
          3.h.sbh,
          msgWidget,
          3.h.sbh
        ],
      );
    });
  }

  Widget _supportBottom() {
    return Container(
      padding: EdgeInsets.symmetric(vertical: 15.h, horizontal: 40.w),
      child: LfButton(
        enabled: true,
        text: strSenFeedback.tr,
        enableColor: color210215,
        onPress: () {
          // toFeedbackPage();
          // ///TODO
        },
      ),
    );
  }

  void _showMoreAction(LfChatDetailLogic logic) {
    List<ActionSheetItem> actions = List.empty(growable: true);
    if (logic.other?.isHiddenForMe() == true ||
        logic.other?.isBlockMe() == true ||
        logic.other?.isEnable() == false ||
        logic.other == null) {
      ///不添加任何内容
    } else {
      actions.add(
        ActionSheetItem(
          action: () {
            logic.jumpProfile();
          },
          title: strViewProfile.tr,
        ),
      );
    }
    if (logic.getMessages().isNotEmpty) {
      actions.add(
        ActionSheetItem(
            action: () async {
              await showActionTips(
                tips: strDeleteConversationTip.tr,
                actionButtonTip: strSure.tr,
                action: () async {
                  await deleteConversation(uid: logic.otherUid);
                },
              );
            },
            title: strDeleteConversation.tr),
      );
    }
    actions.add(
      ActionSheetItem(
          action: () {
            closeSoftKeyboard();
            logic.stopPlayAudio();
            toReportPage(
              userId: logic.otherUid,
            );
          },
          title: strReport.tr.toUpperCase()),
    );
    actions.add(ActionSheetItem(
        action: () {
          blockUser(uid: logic.otherUid);
        },
        title: strBlock.tr));

    showActionSheet(actions: actions);
  }
}

throttle(Function func, int milliseconds) {
  bool enable = true;
  return (val) {
    if (enable == true) {
      enable = false;
      Future.delayed(Duration(milliseconds: milliseconds), () {
        enable = true;
        func(val);
      });
    }
  };
}

debounce(
  Function func, [
  Duration delay = const Duration(milliseconds: 100),
]) {
  Timer? timer;
  return (val) {
    if (timer != null) {
      timer?.cancel();
    }

    timer = Timer(delay, () {
      func(val);
    });
  };
}
